package leesoft.configuration.databeans;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Element;

import leesoft.configuration.core.RuntimeContext;
import leesoft.configuration.interfaces.AfterPlugin;
import leesoft.configuration.interfaces.BeforePlugin;
import leesoft.configuration.interfaces.IXmlToBean;

public class Integration implements IXmlToBean {
	String query;
	List<FieldMap> fieldMapList=new ArrayList<FieldMap>();
	List<Plugin> pluginBefore=new ArrayList<Plugin>();
	List<Plugin> pluginAfter=new ArrayList<Plugin>();
	
	String sourceDS,targetDS;
	String targetTable;
	
	String outputfile;
	
	
	List<BeforePlugin> beforePluginExecutors=new ArrayList<BeforePlugin>();
	List<AfterPlugin> afterPluginExecutors=new ArrayList<AfterPlugin>();
	
	boolean disabled;
	
	
	public List<Plugin> getPluginBefore() {
		return pluginBefore;
	}

	public void setPluginBefore(List<Plugin> pluginBefore) {
		this.pluginBefore = pluginBefore;
	}

	public List<Plugin> getPluginAfter() {
		return pluginAfter;
	}

	public void setPluginAfter(List<Plugin> pluginAfter) {
		this.pluginAfter = pluginAfter;
	}
	
	
	public String getOutputfile() {
		return outputfile;
	}

	public String getSourceDS() {
		return sourceDS;
	}

	public void setSourceDS(String sourceDS) {
		this.sourceDS = sourceDS;
	}

	public String getTargetDS() {
		return targetDS;
	}

	public void setTargetDS(String targetDS) {
		this.targetDS = targetDS;
	}

	@Override
	public void convertXml(Element element) {
		this.query=element.elementText("query");
		this.sourceDS=element.attributeValue("sourceDS");
		this.targetDS=element.attributeValue("targetDS");
		this.targetTable=element.attributeValue("targetTable");
		this.outputfile=element.attributeValue("output");
		if(element.attribute("disabled")!=null){
			this.disabled=true;
		}else{
			this.disabled=false;
		}
		
		List<Element> fieldElements=element.element("map").elements("field");
		for(Element fieldE:fieldElements){
			FieldMap fieldMap=new FieldMap();
			fieldMap.convertXml(fieldE);
			fieldMapList.add(fieldMap);
		}
		
		if(element.element("plugins")==null)
			return;
		
		List<Element> pluginsE=element.element("plugins").elements("plugin");
		
		for(Element pluginE:pluginsE){
			Plugin plugin=new Plugin();
			plugin.convertXml(pluginE);
			String pluginType=pluginE.attributeValue("type");
			if(pluginType==null){
				pluginType="after";
			}
			if(pluginType.equals("before")){
				pluginBefore.add(plugin);
				
				try{
					BeforePlugin bp=(BeforePlugin)Class.forName(plugin.getClassName()).newInstance();
					bp.setRuntimeContext(RuntimeContext.getInstance());
					bp.setParameters(plugin.parametersMap);
					bp.setId(plugin.getId());
					beforePluginExecutors.add(bp);
				}catch(Exception e){
					e.printStackTrace();
				}
			}else{
				pluginAfter.add(plugin);
				try{
					AfterPlugin ap=(AfterPlugin)Class.forName(plugin.getClassName()).newInstance();
					ap.setRuntimeContext(RuntimeContext.getInstance());
					ap.setParameters(plugin.parametersMap);
					ap.setId(plugin.getId());
					afterPluginExecutors.add(ap);
				}catch(Exception e){
					e.printStackTrace();
				}
			}
		}
	}
	
	public String getQuery(){
		return query;
	}
	public List<FieldMap> getFieldMapList(){
		return fieldMapList;
	}
	public String getTargetTable(){
		return targetTable;
	}
	public boolean isDisabled(){
		return disabled;
	}
	
	public void pluginStart(){
		for(BeforePlugin bp:this.beforePluginExecutors){
			bp.beforeExecute();
		}
		for(AfterPlugin ap:this.afterPluginExecutors){
			ap.beforeExecute();
		}
	}
	public void pluginEnd(){
		for(BeforePlugin bp:this.beforePluginExecutors){
			bp.afterExecute();
		}
		for(AfterPlugin ap:this.afterPluginExecutors){
			ap.afterExecute();
		}
	}
	public String beforePluginExecute(String query){
		String retValue=query;
		for(BeforePlugin bp:this.beforePluginExecutors){
			retValue=bp.execute(retValue);
		}
		return retValue;
	}
	public void afterPluginExecute(Map rsMap){
		for(AfterPlugin ap:this.afterPluginExecutors){
			ap.execute(rsMap);
		}
	}
	
}
